#ifndef _CC_EVENT_THREAD_
#define _CC_EVENT_THREAD_

#include "cc_core.h"
#include "cc_port.h"
#include "cc_log.h"

enum
{
  CC_TOPIC_EVENT = 0xff,
};

typedef struct __cc_event_thread cc_event_thread;
typedef struct __cc_event_thread *cc_event_thread_t;

typedef void (*cc_event_notify_cb)(cc_event_thread_t ev_th, cc_mnode_t node);
typedef struct __cc_event_thread
{
  cc_list event_list;
  uint8_t occupy_flag;
  cc_mutex_t mux;
  e_cc_port port_id;
  cc_tid tid;
  void *user_data;
  cc_event_notify_cb topic_cb;
} cc_event_thread, *cc_event_thread_t;

typedef struct
{
  uint32_t event;
  char topic[CC_CONFIG_MSG_TOPIC_MAX_LEN];
  uint8_t data[0];
} cc_event_msg, *cc_event_msg_t;

typedef struct
{
  uint32_t event;
  void *arg;
  char topic[CC_CONFIG_MSG_TOPIC_MAX_LEN];
  cc_event_notify_cb fun_cb;
  cc_list_node node;

} cc_event_handle, *cc_event_handle_t;

#define CC_EVENT_THREAD_MSG_SIZE(sz) MEM_BLOCK_REAL_SIZE(sizeof(cc_event_msg) + sz)

int cc_event_thread_set_occupy_status(cc_event_thread_t ev_th, uint8_t status);
int cc_event_thread_get_occupy_status(cc_event_thread_t ev_th);

cc_event_thread_t cc_event_thread_create(uint32_t port_id,
                                         uint8_t priority, uint32_t stack_size,
                                         uint32_t msg_num, uint32_t msg_size,
                                         cc_event_notify_cb topic_cb);
int cc_event_thread_start(cc_event_thread_t ev_th);
int cc_event_thread_suspend(cc_event_thread_t ev_th);
int cc_event_thread_destroy(cc_event_thread_t ev_th);

// 事件线程API
int cc_event_thread_send_data(cc_event_thread_t ev_th, uint32_t target_port_id, uint32_t event, void *data, uint32_t data_size);
int cc_event_thread_send_cb(cc_event_thread_t ev_th, uint32_t target_port_id, uint32_t event, cc_mn_callback cb);
int cc_event_thread_send_userdata(cc_event_thread_t ev_th, uint32_t target_port_id, uint32_t event, void *user_data);
int cc_event_thread_send_all(cc_event_thread_t ev_th, uint32_t target_port_id, uint32_t event, void *data, uint32_t data_size, void *user_data, cc_mn_callback cb);

int cc_event_thread_publish(cc_event_thread_t ev_th, const char *topic, void *data, uint32_t data_size);
int cc_event_thread_broadcast(cc_event_thread_t ev_th, void *data, uint32_t data_size);

int cc_event_thread_subscribe(cc_event_thread_t ev_th, const char *topic);
int cc_event_thread_notify_attach(cc_event_thread_t ev_th, uint32_t event, cc_event_notify_cb cb);

int cc_event_thread_unsubscribe(cc_event_thread_t ev_th, const char *topic);
int cc_event_thread_notify_detach(cc_event_thread_t ev_th, uint32_t event);
#endif